package com.soccertgc.core.game.requests 
{
	
	import com.soccertgc.core.DataObject;
	import com.soccertgc.core.game.Game;
	import com.soccertgc.core.game.GamePhase;
	import com.soccertgc.logging.Logger;
	import com.soccertgc.utils.JsonUtils;
	import com.soccertgc.utils.StringUtils;

	/**
	 * Abstract class for request parameters
	 * @author ltavecchia
	 * 
	 */	
	public class GameRequestParams extends DataObject
	{
		
		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------
		
		// JSON properties names
		protected static const		JSON_PROPERTY_REQUEST:String             	= "request"; 		// GamePhase.id
		protected static const		JSON_PROPERTY_ROUND_ORDER:String            = "roundOrder";		// Game.turn
		protected static const		JSON_PROPERTY_GAME_ID:String             	= "gameID";
		protected static const		JSON_PROPERTY_USER_ID:String             	= "userID";
		protected static const		JSON_PROPERTY_PASSWORD:String            	= "password";
		protected static const		JSON_PROPERTY_ACTION_JSON:String			= "actionJson";
		protected static const		JSON_PROPERTY_SESSION_TOKEN:String          = "sessionToken";
		protected static const		JSON_PROPERTY_GAME_TOKEN:String             = "gameToken";
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		protected var _phase:GamePhase;
		protected var _turn:int;
		protected var _gameID:uint; 		// LT_TODO: rimpiazzare al più presto con il game token 
		protected var _userID:String;	// LT_TODO: rimpiazzare al più presto con il token di sessione
		protected var _password:String; // LT_TODO: rimpiazzare al più presto con il token di sessione
		protected var _actionData:String; // LT_TODO: usato solo per scopi di test
		
		
		protected var _gameToken:String;
		protected var _sessionToken:String;
		
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTOR
		// -------------------------------------------------------------------------------
		
		public function GameRequestParams()
		{
			if (this is GameRequestParams)
				Logger.warn("GameRequestParams is ABSTRACT and must not be instantiate directly");
		}
		
		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------
		

		public function get phase():GamePhase
		{
			return _phase;
		}
		
		public function set phase(value:GamePhase):void
		{
			_phase = value;
		}
		
		public function get turn():int
		{
			return _turn;
		}
		
		public function set turn(value:int):void
		{
			_turn = value;
		}
		
		public function get gameID():uint
		{
			return _gameID;
		}
		
		public function set gameID(value:uint):void
		{
			_gameID = value;
		}
		
		public function get userID():String
		{
			return _userID;
		}
		
		public function set userID(value:String):void
		{
			_userID = value;
		}
		
		public function get password():String
		{
			return _password;
		}
		
		public function set password(value:String):void
		{
			_password = value;
		}
		
		public function get sessionToken():String
		{
			return _sessionToken;
		}
		
		public function set sessionToken(value:String):void
		{
			_sessionToken = value;
		}
		
		public function get gameToken():String
		{
			return _gameToken;
		}
		
		public function set gameToken(value:String):void
		{
			_gameToken = value;
		}
		
		public function get actionData():String
		{
			return _actionData;
		}
		
		public function set actionData(value:String):void
		{
			_actionData = value;
		}
		
		
		// -------------------------------------------------------------------------------
		// PRIVATE METHODS
		// -------------------------------------------------------------------------------
		
		// DataObject implementation
		
		override protected function validate(data:Object):void
		{
			if (!data.hasOwnProperty(JSON_PROPERTY_REQUEST))	throwLoadMissingPropError(JSON_PROPERTY_REQUEST);
			if (!data.hasOwnProperty(JSON_PROPERTY_GAME_ID))	throwLoadMissingPropError(JSON_PROPERTY_GAME_ID);
			if (!data.hasOwnProperty(JSON_PROPERTY_USER_ID))	throwLoadMissingPropError(JSON_PROPERTY_USER_ID);
			if (!data.hasOwnProperty(JSON_PROPERTY_PASSWORD))	throwLoadMissingPropError(JSON_PROPERTY_PASSWORD);
		}
		
		override protected function fill(data:Object):void
		{
			_phase		= GamePhase.getById(data[JSON_PROPERTY_REQUEST]);
			_gameID 	= int(data[JSON_PROPERTY_GAME_ID]);
			_userID 	= data[JSON_PROPERTY_USER_ID];
			_password	= data[JSON_PROPERTY_PASSWORD];
			if (data.hasOwnProperty(JSON_PROPERTY_ROUND_ORDER)) _turn = data[JSON_PROPERTY_ROUND_ORDER];  
		}
		
		// Virtual methods
		
		protected function createActionData():Object
		{
			Logger.warn("GameRequestParams.createActionJson() is ABSTRACT and must not be overridden in descendant classes");
			return {};
		}
		
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------
		
		/**
		 * Creates the object strucutre to pass as parameters to a Call object for the GameRequest 
		 * who own the parameters
		 * @param params 
		 */		
		public function createCallParams():Object
		{
			var params:Object = new Object();
			params[JSON_PROPERTY_REQUEST] 		= _phase.id;
			params[JSON_PROPERTY_ROUND_ORDER] 	= _turn;
			params[JSON_PROPERTY_GAME_ID] 		= _gameID;
			params[JSON_PROPERTY_USER_ID] 		= _userID;
			params[JSON_PROPERTY_PASSWORD] 		= _password;
			if (StringUtils.isEmpty(_actionData))
			{
				params[JSON_PROPERTY_ACTION_JSON]	= JsonUtils.encode(createActionData());				
			}
			else
			{
				params[JSON_PROPERTY_ACTION_JSON]	= _actionData;
			}
			// LT_TODO: future parameters
			if (!StringUtils.isEmpty(_sessionToken))	params[JSON_PROPERTY_SESSION_TOKEN] = _sessionToken;
			if (!StringUtils.isEmpty(_gameToken))		params[JSON_PROPERTY_GAME_TOKEN] 	= _gameToken;
			return params;
		}
		
		override public function clear():void
		{
			_phase			= GamePhase.RESYNC;
			_gameID			= DataObject.INVALID_ID; 
			_turn			= Game.INVALID_TURN;
			_userID			= "";
			_password		= "";
			_sessionToken	= "";
			_gameToken		= "";
			_actionData		= "";
		}

	}
}